package com.iteaj.iboot.plugin.crawler.controller;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.iteaj.framework.BaseController;
import com.iteaj.framework.logger.Logger;
import com.iteaj.framework.result.BooleanResult;
import com.iteaj.framework.result.Result;
import com.iteaj.framework.security.CheckPermission;
import com.iteaj.framework.security.Logical;
import com.iteaj.iboot.plugin.crawler.entity.Sites;
import com.iteaj.iboot.plugin.crawler.service.ISitesService;
import com.iteaj.iboot.plugin.crawler.sites.SiteResolver;
import com.iteaj.iboot.plugin.crawler.sites.SiteResolverManager;
import com.iteaj.iboot.plugin.crawler.task.CollectSite;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.Future;
import java.util.logging.Level;

/**
 * 爬虫站点管理
 * @author iteaj
 * @since 2024-10-05
 */
@RestController
@RequestMapping("/crawler/sites")
public class SitesController extends BaseController {

    private final SeleniumController selenium;
    private final ThreadPoolTaskExecutor executor;
    private final ISitesService sitesService;
    public static final Map<String, CollectSite> collectSiteMap = new HashMap<>();

    public SitesController(SeleniumController selenium, ThreadPoolTaskExecutor executor, ISitesService sitesService) {
        this.selenium = selenium;
        this.executor = executor;
        this.sitesService = sitesService;
    }

    /**
    * 列表查询
    * @param page 分页
    * @param entity 搜索条件
    */
    @GetMapping("/view")
    @Logger("浏览爬虫站点功能")
    @CheckPermission({"crawler:sites:view"})
    public Result<IPage<Sites>> list(Page<Sites> page, Sites entity) {
        return this.sitesService.page(page, entity);
    }

    /**
     * 站点列表
     * @param entity 查询参数
     * @return 站点列表
     */
    @GetMapping("list")
    public Result<List<Sites>> list(Sites entity) {
        return this.sitesService.list();
    }

    /**
    * 获取编辑记录
    * @param id 记录id
    */
    @GetMapping("/edit")
    @CheckPermission({"crawler:sites:edit"})
    public Result<Sites> getById(Long id) {
        return this.sitesService.getById(id);
    }

    /**
    * 新增或者更新记录
    * @param entity
    */
    @PostMapping("/saveOrUpdate")
    @Logger("新增或者更新爬虫站点记录")
    @CheckPermission(value = {"crawler:sites:edit", "crawler:sites:add"}, logical = Logical.OR)
    public Result<Boolean> saveOrUpdate(@RequestBody Sites entity) {
        return this.sitesService.saveOrUpdate(entity);
    }

    /**
    * 删除指定记录
    * @param idList
    */
    @PostMapping("/del")
    @Logger("删除爬虫站点记录")
    @CheckPermission({"crawler:sites:del"})
    public Result<Boolean> remove(@RequestBody List<Long> idList) {
        return this.sitesService.removeByIds(idList);
    }

    /**
     * 开始采集
     * @param entity 参数
     * @return 是否成功
     */
    @PostMapping("/start")
    public synchronized Result<Boolean> start(@RequestBody Sites entity) {
        if(collectSiteMap.containsKey(entity.getId())) {
            return BooleanResult.buildTrue("采集中...");
        }

        this.selenium.open(null);
        SiteResolver siteResolver = SiteResolverManager.get(entity.getAlias());
        Future<?> submit = executor.submit(siteResolver);
        collectSiteMap.put(entity.getAlias(), new CollectSite(entity.getId(), entity.getAlias(), submit));
        return BooleanResult.buildTrue("开始采集...");
    }

}

